#include "GameController.h"
#include <QMessageBox>
GameController::GameController(QObject *parent)
    : QObject(parent), score(0), rng(std::random_device{}())
{
    board.resize(4, QVector<int>(4, 0));
}

void GameController::startNewGame()
{
    // 重置棋盘和分数
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            board[i][j] = 0;
        }
    }
    score = 0;
    emit scoreUpdated(score);
    
    // 添加两个初始方块
    addRandomTile();
    addRandomTile();
    
    emit boardChanged();
}

void GameController::move(Direction direction)
{
    if (moveTiles(direction)) {
        addRandomTile();
        emit boardChanged();
        emit scoreUpdated(score);
        
        if (isGameWon()) {
            QMessageBox::information(nullptr, "Congratulations!", "You reached 2048! You win!");
        } else if (!isMovePossible()) {
            emit gameOver();
        }
    }
}

void GameController::addRandomTile()
{
    QVector<QPair<int, int>> emptyCells;
    
    // 收集所有空单元格
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (board[i][j] == 0) {
                emptyCells.append(qMakePair(i, j));
            }
        }
    }
    
    if (emptyCells.isEmpty()) {
        return;
    }
    
    // 随机选择一个空单元格
    std::uniform_int_distribution<int> dist(0, emptyCells.size() - 1);
    int index = dist(rng);
    QPair<int, int> cell = emptyCells[index];
    
    // 90% 概率生成 2，10% 概率生成 4
    std::uniform_real_distribution<double> probDist(0.0, 1.0);
    board[cell.first][cell.second] = (probDist(rng) < 0.9) ? 2 : 4;
}

bool GameController::isMovePossible() const
{
    // 检查是否有空单元格
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (board[i][j] == 0) {
                return true;
            }
        }
    }
    
    // 检查是否有可以合并的相邻单元格
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            int current = board[i][j];
            
            // 检查右侧单元格
            if (j < 3 && board[i][j + 1] == current) {
                return true;
            }
            
            // 检查下方单元格
            if (i < 3 && board[i + 1][j] == current) {
                return true;
            }
        }
    }
    
    return false;
}

bool GameController::isGameWon() const
{
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (board[i][j] == 2048) {
                return true;
            }
        }
    }
    return false;
}

bool GameController::moveTiles(Direction direction)
{
    QVector<QVector<int>> oldBoard = board;
    
    // 根据方向移动和合并方块
    switch (direction) {
    case UP:
        for (int j = 0; j < 4; ++j) {
            QVector<int> column;
            for (int i = 0; i < 4; ++i) {
                if (board[i][j] != 0) {
                    column.append(board[i][j]);
                }
            }
            
            // 合并相同的数字
            for (int i = 0; i < column.size() - 1; ++i) {
                if (column[i] == column[i + 1]) {
                    column[i] *= 2;
                    score += column[i];
                    column.remove(i + 1);
                }
            }
            
            // 更新列
            for (int i = 0; i < 4; ++i) {
                board[i][j] = (i < column.size()) ? column[i] : 0;
            }
        }
        break;
        
    case DOWN:
        for (int j = 0; j < 4; ++j) {
            QVector<int> column;
            for (int i = 3; i >= 0; --i) {
                if (board[i][j] != 0) {
                    column.append(board[i][j]);
                }
            }
            
            // 合并相同的数字
            for (int i = 0; i < column.size() - 1; ++i) {
                if (column[i] == column[i + 1]) {
                    column[i] *= 2;
                    score += column[i];
                    column.remove(i + 1);
                }
            }
            
            // 更新列
            for (int i = 0; i < 4; ++i) {
                board[3 - i][j] = (i < column.size()) ? column[i] : 0;
            }
        }
        break;
        
    case LEFT:
        for (int i = 0; i < 4; ++i) {
            QVector<int> row;
            for (int j = 0; j < 4; ++j) {
                if (board[i][j] != 0) {
                    row.append(board[i][j]);
                }
            }
            
            // 合并相同的数字
            for (int j = 0; j < row.size() - 1; ++j) {
                if (row[j] == row[j + 1]) {
                    row[j] *= 2;
                    score += row[j];
                    row.remove(j + 1);
                }
            }
            
            // 更新行
            for (int j = 0; j < 4; ++j) {
                board[i][j] = (j < row.size()) ? row[j] : 0;
            }
        }
        break;
        
    case RIGHT:
        for (int i = 0; i < 4; ++i) {
            QVector<int> row;
            for (int j = 3; j >= 0; --j) {
                if (board[i][j] != 0) {
                    row.append(board[i][j]);
                }
            }
            
            // 合并相同的数字
            for (int j = 0; j < row.size() - 1; ++j) {
                if (row[j] == row[j + 1]) {
                    row[j] *= 2;
                    score += row[j];
                    row.remove(j + 1);
                }
            }
            
            // 更新行
            for (int j = 0; j < 4; ++j) {
                board[i][3 - j] = (j < row.size()) ? row[j] : 0;
            }
        }
        break;
    }
    
    // 检查棋盘是否发生变化
    return board != oldBoard;
}
